import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.regex.*;

/**
 * @Author Lollipop
 * @Date 2025/4/10 15:00
 * @Description 生成项目结构树，支持Javadoc注释提取
 */
@Slf4j
public class EnhancedProjectTreeGenerator {
    // 需要忽略的目录/文件
    private static final List<String> IGNORED = Arrays.asList(".git", ".idea", "target", "build", "node_modules");

    // 匹配Javadoc注释的正则表达式
    private static final Pattern JAVA_DOC_PATTERN = Pattern.compile("/\\*\\*(.*?)\\*/", Pattern.DOTALL);
    // 匹配类/接口声明的正则表达式
    private static final Pattern CLASS_PATTERN = Pattern.compile("\\b(class|interface|enum)\\s+(\\w+)");

    public static void main(String[] args) {
        String projectRoot = ".";
        String outputFile = "README.md";

        try {
            String tree = generateTreeWithDocs(new File(projectRoot), 0);
            writeToFile(outputFile, tree);
            log.info("项目结构树已生成到{} ", outputFile);
        } catch (IOException e) {
            log.error("生成失败:{}", e.getMessage());
        }
    }

    private static String generateTreeWithDocs(File dir, int depth) throws IOException {
        StringBuilder sb = new StringBuilder();
        String indent = "│   ".repeat(depth);

        File[] files = dir.listFiles();
        if (files == null) return "";

        // 排序：目录在前，文件在后
        Arrays.sort(files, (f1, f2) -> {
            if (f1.isDirectory() && !f2.isDirectory()) return -1;
            if (!f1.isDirectory() && f2.isDirectory()) return 1;
            return f1.getName().compareTo(f2.getName());
        });

        for (int i = 0; i < files.length; i++) {
            File file = files[i];
            if (IGNORED.contains(file.getName())) continue;

            boolean isLast = (i == files.length - 1);
            String prefix = isLast ? "└── " : "├── ";

            if (file.isDirectory()) {
                String dirDesc = getDirectoryDescription(file);
                sb.append(indent).append(prefix).append(file.getName()).append("/")
                        .append("  # ").append(dirDesc).append("\n");
                sb.append(generateTreeWithDocs(file, depth + 1));
            } else if (file.getName().endsWith(".java")) {
                String classDesc = getClassDescription(file);
                sb.append(indent).append(prefix).append(file.getName())
                        .append("  # ").append(classDesc).append("\n");
            } else {
                sb.append(indent).append(prefix).append(file.getName()).append("\n");
            }
        }
        return sb.toString();
    }

    // 获取目录描述（默认使用目录名）
    private static String getDirectoryDescription(File dir) {
        return switch (dir.getName()) {
            case "src" -> "项目源代码根目录";
            case "main" -> "主代码目录";
            case "test" -> "测试代码目录";
            case "java" -> "Java源代码";
            case "resources" -> "资源文件目录";
            default -> dir.getName() + "目录";
        };
    }

    // 从Java文件提取类描述
    private static String getClassDescription(File javaFile) throws IOException {
        String content = Files.readString(javaFile.toPath());

        // 提取Javadoc注释
        Matcher docMatcher = JAVA_DOC_PATTERN.matcher(content);
        if (docMatcher.find()) {
            String javadoc = docMatcher.group(1)
                    // 去除换行和多余空格
                    .replaceAll("[\\r\\n\\s]+", " ")
                    .trim();

            // 提取 @Description 后面的内容
            Pattern DescriptionPattern = Pattern.compile("@Description\\s+(.*)");
            Matcher DescriptionMatcher = DescriptionPattern.matcher(javadoc);
            if (DescriptionMatcher.find()) {
                return DescriptionMatcher.group(1).trim();
            }
        }

        // 提取类名作为备用描述
        Matcher classMatcher = CLASS_PATTERN.matcher(content);
        if (classMatcher.find()) {
            return classMatcher.group(2) + "类";
        }

        return "未添加描述";
    }


    private static void writeToFile(String filename, String content) throws IOException {
        try (FileWriter writer = new FileWriter(filename)) {
            writer.write("# 项目结构\n```\n");
            writer.write(content);
            writer.write("```\n");
        }
    }
}